/*
 * Copyright (C) 2011, EADS France
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 */

package xowl.interpreter.impl;

import java.util.List;

/**
 *
 * @author Laurent WOUTERS
 */
public abstract class AbstractEvaluator implements Evaluator {
    @Override public abstract boolean can(xowl.lang.owl2.Expression exp);
    @Override public abstract boolean can(xowl.lang.actions.Query exp);

    // <editor-fold defaultstate="collapsed" desc="Multityped expressions">
    protected xowl.lang.runtime.Array eval_ValuesOf(Evaluator parent, xowl.lang.actions.ValuesOf query) throws xowl.interpreter.XOWLException {
        List<xowl.interpreter.QuerySolution> results = select(parent, query);
        xowl.lang.runtime.Array array = new xowl.lang.runtime.Array();
        int index = 0;
        for (xowl.interpreter.QuerySolution solution : results) {
            xowl.lang.runtime.Value value = solution.getValue(query.getOn());
            if (value != null) {
                xowl.lang.runtime.Element temp = new xowl.lang.runtime.Element();
                temp.setIndex(index);
                temp.setValue(value);
                array.addElements(temp);
                index++;
            }
        }
        return array;
    }
    protected xowl.lang.runtime.Value eval_ValueOf(Evaluator parent, xowl.lang.actions.ValueOf query) throws xowl.interpreter.XOWLException {
        List<xowl.interpreter.QuerySolution> results = select(parent, query);
        if (results.isEmpty())
            return null;
        return results.get(0).getValue(query.getOn());
    }
    protected abstract xowl.lang.runtime.Value eval_Contains(Evaluator parent, xowl.lang.actions.Contains query) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Value eval_Invoke(Evaluator parent, xowl.lang.actions.Invoke expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Value eval_Execute(Evaluator parent, xowl.lang.actions.Execute expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Value eval_QueryVariable(Evaluator parent, xowl.lang.actions.QueryVariable expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Value eval_CodeVariable(Evaluator parent, xowl.lang.actions.CodeVariable expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Value eval_ArrayElement(Evaluator parent, xowl.lang.actions.ArrayElement expression) throws xowl.interpreter.XOWLException;
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="evalEntity">
    @Override public xowl.lang.runtime.Entity evalEntity(Evaluator parent, xowl.lang.owl2.EntityExpression expression) throws xowl.interpreter.XOWLException {
        if (expression == null) return null;
        if (expression instanceof xowl.lang.actions.Invoke)
            return parent.toEntity(eval_Invoke(parent, (xowl.lang.actions.Invoke)expression));
        if (expression instanceof xowl.lang.actions.Execute)
            return parent.toEntity(eval_Execute(parent, (xowl.lang.actions.Execute)expression));
        if (expression instanceof xowl.lang.actions.ValueOf)
            return parent.toEntity(eval_ValueOf(parent, (xowl.lang.actions.ValueOf)expression));
        if (expression instanceof xowl.lang.actions.CodeVariable)
            return parent.toEntity(eval_CodeVariable(parent, (xowl.lang.actions.CodeVariable)expression));
        if (expression instanceof xowl.lang.actions.QueryVariable)
            return parent.toEntity(eval_QueryVariable(parent, (xowl.lang.actions.QueryVariable)expression));
        if (expression instanceof xowl.lang.actions.ArrayElement)
            return parent.toEntity(eval_ArrayElement(parent, (xowl.lang.actions.ArrayElement)expression));
        if (expression instanceof xowl.lang.interop.JavaInvokation)
            return parent.toEntity(eval_JavaInvokation(parent, (xowl.lang.interop.JavaInvokation)expression));
        if (expression instanceof xowl.lang.interop.ObjectField)
            return parent.toEntity(eval_ObjectField(parent, (xowl.lang.interop.ObjectField)expression));
        if (expression instanceof xowl.lang.interop.StaticField)
            return parent.toEntity(eval_StaticField(parent, (xowl.lang.interop.StaticField)expression));
        if (expression instanceof xowl.lang.actions.NewEntity)
            return eval_NewEntity(parent, (xowl.lang.actions.NewEntity)expression);
        if (expression instanceof xowl.lang.actions.EntityForIRI)
            return eval_EntityForIRI(parent, (xowl.lang.actions.EntityForIRI)expression);

        if (expression instanceof xowl.lang.owl2.IRI) return eval_Entity(parent, (xowl.lang.owl2.IRI)expression);
        throw getUnknownExpression(expression);
    }
    protected abstract xowl.lang.runtime.Entity eval_Entity(Evaluator parent, xowl.lang.owl2.IRI expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Entity eval_NewEntity(Evaluator parent, xowl.lang.actions.NewEntity expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Entity eval_EntityForIRI(Evaluator parent, xowl.lang.actions.EntityForIRI expression) throws xowl.interpreter.XOWLException;
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="evalClass">
    @Override public xowl.lang.runtime.Class evalClass(Evaluator parent, xowl.lang.owl2.ClassExpression expression) throws xowl.interpreter.XOWLException {
        if (expression == null) return null;
        if (expression instanceof xowl.lang.actions.Invoke)
            return parent.toClass(eval_Invoke(parent, (xowl.lang.actions.Invoke)expression));
        if (expression instanceof xowl.lang.actions.Execute)
            return parent.toClass(eval_Execute(parent, (xowl.lang.actions.Execute)expression));
        if (expression instanceof xowl.lang.actions.ValueOf)
            return parent.toClass(eval_ValueOf(parent, (xowl.lang.actions.ValueOf)expression));
        if (expression instanceof xowl.lang.actions.CodeVariable)
            return parent.toClass(eval_CodeVariable(parent, (xowl.lang.actions.CodeVariable)expression));
        if (expression instanceof xowl.lang.actions.QueryVariable)
            return parent.toClass(eval_QueryVariable(parent, (xowl.lang.actions.QueryVariable)expression));
        if (expression instanceof xowl.lang.actions.ArrayElement)
            return parent.toClass(eval_ArrayElement(parent, (xowl.lang.actions.ArrayElement)expression));
        if (expression instanceof xowl.lang.interop.JavaInvokation)
            return parent.toClass(eval_JavaInvokation(parent, (xowl.lang.interop.JavaInvokation)expression));
        if (expression instanceof xowl.lang.interop.ObjectField)
            return parent.toClass(eval_ObjectField(parent, (xowl.lang.interop.ObjectField)expression));
        if (expression instanceof xowl.lang.interop.StaticField)
            return parent.toClass(eval_StaticField(parent, (xowl.lang.interop.StaticField)expression));
        if (expression instanceof xowl.lang.owl2.IRI) return eval_Class(parent, (xowl.lang.owl2.IRI)expression);
        if (expression instanceof xowl.lang.owl2.ObjectUnionOf) return eval_ObjectUnionOf(parent, (xowl.lang.owl2.ObjectUnionOf)expression);
        if (expression instanceof xowl.lang.owl2.ObjectIntersectionOf) return eval_ObjectIntersectionOf(parent, (xowl.lang.owl2.ObjectIntersectionOf)expression);
        if (expression instanceof xowl.lang.owl2.ObjectOneOf) return eval_ObjectOneOf(parent, (xowl.lang.owl2.ObjectOneOf)expression);
        if (expression instanceof xowl.lang.owl2.ObjectComplementOf) return eval_ObjectComplementOf(parent, (xowl.lang.owl2.ObjectComplementOf)expression);
        if (expression instanceof xowl.lang.owl2.DataAllValuesFrom) return eval_DataAllValuesFrom(parent, (xowl.lang.owl2.DataAllValuesFrom)expression);
        if (expression instanceof xowl.lang.owl2.DataExactCardinality) return eval_DataExactCardinality(parent, (xowl.lang.owl2.DataExactCardinality)expression);
        if (expression instanceof xowl.lang.owl2.DataHasValue) return eval_DataHasValue(parent, (xowl.lang.owl2.DataHasValue)expression);
        if (expression instanceof xowl.lang.owl2.DataMaxCardinality) return eval_DataMaxCardinality(parent, (xowl.lang.owl2.DataMaxCardinality)expression);
        if (expression instanceof xowl.lang.owl2.DataMinCardinality) return eval_DataMinCardinality(parent, (xowl.lang.owl2.DataMinCardinality)expression);
        if (expression instanceof xowl.lang.owl2.DataSomeValuesFrom) return eval_DataSomeValuesFrom(parent, (xowl.lang.owl2.DataSomeValuesFrom)expression);
        if (expression instanceof xowl.lang.owl2.ObjectAllValuesFrom) return eval_ObjectAllValuesFrom(parent, (xowl.lang.owl2.ObjectAllValuesFrom)expression);
        if (expression instanceof xowl.lang.owl2.ObjectExactCardinality) return eval_ObjectExactCardinality(parent, (xowl.lang.owl2.ObjectExactCardinality)expression);
        if (expression instanceof xowl.lang.owl2.ObjectHasSelf) return eval_ObjectHasSelf(parent, (xowl.lang.owl2.ObjectHasSelf)expression);
        if (expression instanceof xowl.lang.owl2.ObjectHasValue) return eval_ObjectHasValue(parent, (xowl.lang.owl2.ObjectHasValue)expression);
        if (expression instanceof xowl.lang.owl2.ObjectMaxCardinality) return eval_ObjectMaxCardinality(parent, (xowl.lang.owl2.ObjectMaxCardinality)expression);
        if (expression instanceof xowl.lang.owl2.ObjectMinCardinality) return eval_ObjectMinCardinality(parent, (xowl.lang.owl2.ObjectMinCardinality)expression);
        if (expression instanceof xowl.lang.owl2.ObjectSomeValuesFrom) return eval_ObjectSomeValuesFrom(parent, (xowl.lang.owl2.ObjectSomeValuesFrom)expression);
        throw getUnknownExpression(expression);
    }
    protected abstract xowl.lang.runtime.Class eval_Class(Evaluator parent, xowl.lang.owl2.IRI expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Class eval_ObjectUnionOf(Evaluator parent, xowl.lang.owl2.ObjectUnionOf expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Class eval_ObjectIntersectionOf(Evaluator parent, xowl.lang.owl2.ObjectIntersectionOf expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Class eval_ObjectOneOf(Evaluator parent, xowl.lang.owl2.ObjectOneOf expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Class eval_ObjectComplementOf(Evaluator parent, xowl.lang.owl2.ObjectComplementOf expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Class eval_DataAllValuesFrom(Evaluator parent, xowl.lang.owl2.DataAllValuesFrom expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Class eval_DataExactCardinality(Evaluator parent, xowl.lang.owl2.DataExactCardinality expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Class eval_DataHasValue(Evaluator parent, xowl.lang.owl2.DataHasValue expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Class eval_DataMaxCardinality(Evaluator parent, xowl.lang.owl2.DataMaxCardinality expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Class eval_DataMinCardinality(Evaluator parent, xowl.lang.owl2.DataMinCardinality expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Class eval_DataSomeValuesFrom(Evaluator parent, xowl.lang.owl2.DataSomeValuesFrom expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Class eval_ObjectAllValuesFrom(Evaluator parent, xowl.lang.owl2.ObjectAllValuesFrom expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Class eval_ObjectExactCardinality(Evaluator parent, xowl.lang.owl2.ObjectExactCardinality expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Class eval_ObjectHasSelf(Evaluator parent, xowl.lang.owl2.ObjectHasSelf expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Class eval_ObjectHasValue(Evaluator parent, xowl.lang.owl2.ObjectHasValue expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Class eval_ObjectMaxCardinality(Evaluator parent, xowl.lang.owl2.ObjectMaxCardinality expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Class eval_ObjectMinCardinality(Evaluator parent, xowl.lang.owl2.ObjectMinCardinality expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Class eval_ObjectSomeValuesFrom(Evaluator parent, xowl.lang.owl2.ObjectSomeValuesFrom expression) throws xowl.interpreter.XOWLException;
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="evalObjProp">
    @Override public xowl.lang.runtime.ObjectProperty evalObjProp(Evaluator parent, xowl.lang.owl2.ObjectPropertyExpression expression) throws xowl.interpreter.XOWLException {
        if (expression == null) return null;
        if (expression instanceof xowl.lang.actions.Invoke)
            return parent.toObjProp(eval_Invoke(parent, (xowl.lang.actions.Invoke)expression));
        if (expression instanceof xowl.lang.actions.Execute)
            return parent.toObjProp(eval_Execute(parent, (xowl.lang.actions.Execute)expression));
        if (expression instanceof xowl.lang.actions.ValueOf)
            return parent.toObjProp(eval_ValueOf(parent, (xowl.lang.actions.ValueOf)expression));
        if (expression instanceof xowl.lang.actions.CodeVariable)
            return parent.toObjProp(eval_CodeVariable(parent, (xowl.lang.actions.CodeVariable)expression));
        if (expression instanceof xowl.lang.actions.QueryVariable)
            return parent.toObjProp(eval_QueryVariable(parent, (xowl.lang.actions.QueryVariable)expression));
        if (expression instanceof xowl.lang.actions.ArrayElement)
            return parent.toObjProp(eval_ArrayElement(parent, (xowl.lang.actions.ArrayElement)expression));
        if (expression instanceof xowl.lang.interop.JavaInvokation)
            return parent.toObjProp(eval_JavaInvokation(parent, (xowl.lang.interop.JavaInvokation)expression));
        if (expression instanceof xowl.lang.interop.ObjectField)
            return parent.toObjProp(eval_ObjectField(parent, (xowl.lang.interop.ObjectField)expression));
        if (expression instanceof xowl.lang.interop.StaticField)
            return parent.toObjProp(eval_StaticField(parent, (xowl.lang.interop.StaticField)expression));
        if (expression instanceof xowl.lang.owl2.IRI) return eval_ObjectProperty(parent, (xowl.lang.owl2.IRI)expression);
        if (expression instanceof xowl.lang.owl2.ObjectInverseOf) return eval_ObjectInverseOf(parent, (xowl.lang.owl2.ObjectInverseOf)expression);
        throw getUnknownExpression(expression);
    }
    protected abstract xowl.lang.runtime.ObjectProperty eval_ObjectProperty(Evaluator parent, xowl.lang.owl2.IRI expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.ObjectProperty eval_ObjectInverseOf(Evaluator parent, xowl.lang.owl2.ObjectInverseOf expression) throws xowl.interpreter.XOWLException;
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="evalDataProp">
    @Override public xowl.lang.runtime.DataProperty evalDataProp(Evaluator parent, xowl.lang.owl2.DataPropertyExpression expression) throws xowl.interpreter.XOWLException {
        if (expression == null) return null;
        if (expression instanceof xowl.lang.actions.Invoke)
            return parent.toDataProp(eval_Invoke(parent, (xowl.lang.actions.Invoke)expression));
        if (expression instanceof xowl.lang.actions.Execute)
            return parent.toDataProp(eval_Execute(parent, (xowl.lang.actions.Execute)expression));
        if (expression instanceof xowl.lang.actions.ValueOf)
            return parent.toDataProp(eval_ValueOf(parent, (xowl.lang.actions.ValueOf)expression));
        if (expression instanceof xowl.lang.actions.CodeVariable)
            return parent.toDataProp(eval_CodeVariable(parent, (xowl.lang.actions.CodeVariable)expression));
        if (expression instanceof xowl.lang.actions.QueryVariable)
            return parent.toDataProp(eval_QueryVariable(parent, (xowl.lang.actions.QueryVariable)expression));
        if (expression instanceof xowl.lang.actions.ArrayElement)
            return parent.toDataProp(eval_ArrayElement(parent, (xowl.lang.actions.ArrayElement)expression));
        if (expression instanceof xowl.lang.interop.JavaInvokation)
            return parent.toDataProp(eval_JavaInvokation(parent, (xowl.lang.interop.JavaInvokation)expression));
        if (expression instanceof xowl.lang.interop.ObjectField)
            return parent.toDataProp(eval_ObjectField(parent, (xowl.lang.interop.ObjectField)expression));
        if (expression instanceof xowl.lang.interop.StaticField)
            return parent.toDataProp(eval_StaticField(parent, (xowl.lang.interop.StaticField)expression));
        if (expression instanceof xowl.lang.owl2.IRI) return eval_DataProperty(parent, (xowl.lang.owl2.IRI)expression);
        throw getUnknownExpression(expression);
    }
    protected abstract xowl.lang.runtime.DataProperty eval_DataProperty(Evaluator parent, xowl.lang.owl2.IRI expression) throws xowl.interpreter.XOWLException;
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="evalDatatype">
    @Override public xowl.lang.runtime.Datatype evalDatatype(Evaluator parent, xowl.lang.owl2.Datarange expression) throws xowl.interpreter.XOWLException {
        if (expression == null) return null;
        if (expression instanceof xowl.lang.actions.Invoke)
            return parent.toDatatype(eval_Invoke(parent, (xowl.lang.actions.Invoke)expression));
        if (expression instanceof xowl.lang.actions.Execute)
            return parent.toDatatype(eval_Execute(parent, (xowl.lang.actions.Execute)expression));
        if (expression instanceof xowl.lang.actions.ValueOf)
            return parent.toDatatype(eval_ValueOf(parent, (xowl.lang.actions.ValueOf)expression));
        if (expression instanceof xowl.lang.actions.CodeVariable)
            return parent.toDatatype(eval_CodeVariable(parent, (xowl.lang.actions.CodeVariable)expression));
        if (expression instanceof xowl.lang.actions.QueryVariable)
            return parent.toDatatype(eval_QueryVariable(parent, (xowl.lang.actions.QueryVariable)expression));
        if (expression instanceof xowl.lang.actions.ArrayElement)
            return parent.toDatatype(eval_ArrayElement(parent, (xowl.lang.actions.ArrayElement)expression));
        if (expression instanceof xowl.lang.interop.JavaInvokation)
            return parent.toDatatype(eval_JavaInvokation(parent, (xowl.lang.interop.JavaInvokation)expression));
        if (expression instanceof xowl.lang.interop.ObjectField)
            return parent.toDatatype(eval_ObjectField(parent, (xowl.lang.interop.ObjectField)expression));
        if (expression instanceof xowl.lang.interop.StaticField)
            return parent.toDatatype(eval_StaticField(parent, (xowl.lang.interop.StaticField)expression));
        if (expression instanceof xowl.lang.owl2.IRI) return eval_Datatype(parent, (xowl.lang.owl2.IRI)expression);
        if (expression instanceof xowl.lang.owl2.DataComplementOf) return eval_DataComplementOf(parent, (xowl.lang.owl2.DataComplementOf)expression);
        if (expression instanceof xowl.lang.owl2.DataIntersectionOf) return eval_DataIntersectionOf(parent, (xowl.lang.owl2.DataIntersectionOf)expression);
        if (expression instanceof xowl.lang.owl2.DataOneOf) return eval_DataOneOf(parent, (xowl.lang.owl2.DataOneOf)expression);
        if (expression instanceof xowl.lang.owl2.DatatypeRestriction) return eval_DatatypeRestriction(parent, (xowl.lang.owl2.DatatypeRestriction)expression);
        if (expression instanceof xowl.lang.owl2.DataUnionOf) return eval_DataUnionOf(parent, (xowl.lang.owl2.DataUnionOf)expression);
        throw getUnknownExpression(expression);
    }
    protected abstract xowl.lang.runtime.Datatype eval_Datatype(Evaluator parent, xowl.lang.owl2.IRI expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Datatype eval_DataComplementOf(Evaluator parent, xowl.lang.owl2.DataComplementOf expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Datatype eval_DataIntersectionOf(Evaluator parent, xowl.lang.owl2.DataIntersectionOf expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Datatype eval_DataOneOf(Evaluator parent, xowl.lang.owl2.DataOneOf expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Datatype eval_DatatypeRestriction(Evaluator parent, xowl.lang.owl2.DatatypeRestriction expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Datatype eval_DataUnionOf(Evaluator parent, xowl.lang.owl2.DataUnionOf expression) throws xowl.interpreter.XOWLException;
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="evalIndividual">
    @Override public xowl.lang.runtime.Individual evalIndividual(Evaluator parent, xowl.lang.owl2.IndividualExpression expression) throws xowl.interpreter.XOWLException {
        if (expression == null) return null;
        if (expression instanceof xowl.lang.actions.Invoke)
            return parent.toIndividual(eval_Invoke(parent, (xowl.lang.actions.Invoke)expression));
        if (expression instanceof xowl.lang.actions.Execute)
            return parent.toIndividual(eval_Execute(parent, (xowl.lang.actions.Execute)expression));
        if (expression instanceof xowl.lang.actions.ValueOf)
            return parent.toIndividual(eval_ValueOf(parent, (xowl.lang.actions.ValueOf)expression));
        if (expression instanceof xowl.lang.actions.CodeVariable)
            return parent.toIndividual(eval_CodeVariable(parent, (xowl.lang.actions.CodeVariable)expression));
        if (expression instanceof xowl.lang.actions.QueryVariable)
            return parent.toIndividual(eval_QueryVariable(parent, (xowl.lang.actions.QueryVariable)expression));
        if (expression instanceof xowl.lang.actions.ArrayElement)
            return parent.toIndividual(eval_ArrayElement(parent, (xowl.lang.actions.ArrayElement)expression));
        if (expression instanceof xowl.lang.interop.JavaInvokation)
            return parent.toIndividual(eval_JavaInvokation(parent, (xowl.lang.interop.JavaInvokation)expression));
        if (expression instanceof xowl.lang.interop.ObjectField)
            return parent.toIndividual(eval_ObjectField(parent, (xowl.lang.interop.ObjectField)expression));
        if (expression instanceof xowl.lang.interop.StaticField)
            return parent.toIndividual(eval_StaticField(parent, (xowl.lang.interop.StaticField)expression));
        if (expression instanceof xowl.lang.actions.NewIndividual)
            return eval_NewIndividual(parent, (xowl.lang.actions.NewIndividual)expression);
        if (expression instanceof xowl.lang.owl2.IRI) return eval_NamedIndividual(parent, (xowl.lang.owl2.IRI)expression);
        if (expression instanceof xowl.lang.owl2.AnonymousIndividual) return eval_AnonymousIndividual(parent, (xowl.lang.owl2.AnonymousIndividual)expression);
        throw getUnknownExpression(expression);
    }
    protected abstract xowl.lang.runtime.Individual eval_NamedIndividual(Evaluator parent, xowl.lang.owl2.IRI expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Individual eval_AnonymousIndividual(Evaluator parent, xowl.lang.owl2.AnonymousIndividual expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Individual eval_NewIndividual(Evaluator parent, xowl.lang.actions.NewIndividual expression) throws xowl.interpreter.XOWLException;
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="evalLiteral">
    @Override public xowl.lang.runtime.Literal evalLiteral(Evaluator parent, xowl.lang.owl2.LiteralExpression expression) throws xowl.interpreter.XOWLException {
        if (expression == null) return null;
        if (expression instanceof xowl.lang.actions.Invoke)
            return parent.toLiteral(eval_Invoke(parent, (xowl.lang.actions.Invoke)expression));
        if (expression instanceof xowl.lang.actions.Execute)
            return parent.toLiteral(eval_Execute(parent, (xowl.lang.actions.Execute)expression));
        if (expression instanceof xowl.lang.actions.Contains)
            return parent.toLiteral(eval_Contains(parent, (xowl.lang.actions.Contains)expression));
        if (expression instanceof xowl.lang.actions.ValueOf)
            return parent.toLiteral(eval_ValueOf(parent, (xowl.lang.actions.ValueOf)expression));
        if (expression instanceof xowl.lang.actions.CodeVariable)
            return parent.toLiteral(eval_CodeVariable(parent, (xowl.lang.actions.CodeVariable)expression));
        if (expression instanceof xowl.lang.actions.QueryVariable)
            return parent.toLiteral(eval_QueryVariable(parent, (xowl.lang.actions.QueryVariable)expression));
        if (expression instanceof xowl.lang.actions.ArrayElement)
            return parent.toLiteral(eval_ArrayElement(parent, (xowl.lang.actions.ArrayElement)expression));
        if (expression instanceof xowl.lang.interop.JavaInvokation)
            return parent.toLiteral(eval_JavaInvokation(parent, (xowl.lang.interop.JavaInvokation)expression));
        if (expression instanceof xowl.lang.interop.ObjectField)
            return parent.toLiteral(eval_ObjectField(parent, (xowl.lang.interop.ObjectField)expression));
        if (expression instanceof xowl.lang.interop.StaticField)
            return parent.toLiteral(eval_StaticField(parent, (xowl.lang.interop.StaticField)expression));
        if (expression instanceof xowl.lang.actions.Plus)
            return eval_Plus(parent, (xowl.lang.actions.Plus)expression);
        if (expression instanceof xowl.lang.actions.Minus)
            return eval_Minus(parent, (xowl.lang.actions.Minus)expression);
        if (expression instanceof xowl.lang.actions.Mult)
            return eval_Mult(parent, (xowl.lang.actions.Mult)expression);
        if (expression instanceof xowl.lang.actions.Divide)
            return eval_Divide(parent, (xowl.lang.actions.Divide)expression);
        if (expression instanceof xowl.lang.actions.Modulus)
            return eval_Modulus(parent, (xowl.lang.actions.Modulus)expression);
        if (expression instanceof xowl.lang.actions.BAnd)
            return eval_BAnd(parent, (xowl.lang.actions.BAnd)expression);
        if (expression instanceof xowl.lang.actions.BOr)
            return eval_BOr(parent, (xowl.lang.actions.BOr)expression);
        if (expression instanceof xowl.lang.actions.BXOr)
            return eval_BXOr(parent, (xowl.lang.actions.BXOr)expression);
        if (expression instanceof xowl.lang.actions.BNot)
            return eval_BNot(parent, (xowl.lang.actions.BNot)expression);
        if (expression instanceof xowl.lang.actions.Equal)
            return eval_Equal(parent, (xowl.lang.actions.Equal)expression);
        if (expression instanceof xowl.lang.actions.Different)
            return eval_Different(parent, (xowl.lang.actions.Different)expression);
        if (expression instanceof xowl.lang.actions.Greater)
            return eval_Greater(parent, (xowl.lang.actions.Greater)expression);
        if (expression instanceof xowl.lang.actions.GreaterEqual)
            return eval_GreaterEqual(parent, (xowl.lang.actions.GreaterEqual)expression);
        if (expression instanceof xowl.lang.actions.Lesser)
            return eval_Lesser(parent, (xowl.lang.actions.Lesser)expression);
        if (expression instanceof xowl.lang.actions.LesserEqual)
            return eval_LesserEqual(parent, (xowl.lang.actions.LesserEqual)expression);
        if (expression instanceof xowl.lang.actions.IRIOf)
            return eval_IRIOf(parent, (xowl.lang.actions.IRIOf)expression);
        if (expression instanceof xowl.lang.actions.LengthOf)
            return eval_LengthOf(parent, (xowl.lang.actions.LengthOf)expression);
        if (expression instanceof xowl.lang.owl2.Literal) return eval_Literal(parent, (xowl.lang.owl2.Literal)expression);
        throw getUnknownExpression(expression);
    }
    protected abstract xowl.lang.runtime.Literal eval_Literal(Evaluator parent, xowl.lang.owl2.Literal expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Literal eval_Plus(Evaluator parent, xowl.lang.actions.Plus expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Literal eval_Minus(Evaluator parent, xowl.lang.actions.Minus expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Literal eval_Mult(Evaluator parent, xowl.lang.actions.Mult expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Literal eval_Divide(Evaluator parent, xowl.lang.actions.Divide expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Literal eval_Modulus(Evaluator parent, xowl.lang.actions.Modulus expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Literal eval_BAnd(Evaluator parent, xowl.lang.actions.BAnd expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Literal eval_BOr(Evaluator parent, xowl.lang.actions.BOr expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Literal eval_BXOr(Evaluator parent, xowl.lang.actions.BXOr expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Literal eval_BNot(Evaluator parent, xowl.lang.actions.BNot expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Literal eval_Equal(Evaluator parent, xowl.lang.actions.Equal expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Literal eval_Different(Evaluator parent, xowl.lang.actions.Different expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Literal eval_Greater(Evaluator parent, xowl.lang.actions.Greater expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Literal eval_GreaterEqual(Evaluator parent, xowl.lang.actions.GreaterEqual expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Literal eval_Lesser(Evaluator parent, xowl.lang.actions.Lesser expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Literal eval_LesserEqual(Evaluator parent, xowl.lang.actions.LesserEqual expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Literal eval_IRIOf(Evaluator parent, xowl.lang.actions.IRIOf expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Literal eval_LengthOf(Evaluator parent, xowl.lang.actions.LengthOf expression) throws xowl.interpreter.XOWLException;
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="evalFunction">
    @Override public xowl.lang.runtime.Function evalFunction(Evaluator parent, xowl.lang.actions.FunctionExpression expression) throws xowl.interpreter.XOWLException {
        if (expression == null) return null;
        if (expression instanceof xowl.lang.actions.Invoke)
            return parent.toFunction(eval_Invoke(parent, (xowl.lang.actions.Invoke)expression));
        if (expression instanceof xowl.lang.actions.Execute)
            return parent.toFunction(eval_Execute(parent, (xowl.lang.actions.Execute)expression));
        if (expression instanceof xowl.lang.actions.ValueOf)
            return parent.toFunction(eval_ValueOf(parent, (xowl.lang.actions.ValueOf)expression));
        if (expression instanceof xowl.lang.actions.CodeVariable)
            return parent.toFunction(eval_CodeVariable(parent, (xowl.lang.actions.CodeVariable)expression));
        if (expression instanceof xowl.lang.actions.QueryVariable)
            return parent.toFunction(eval_QueryVariable(parent, (xowl.lang.actions.QueryVariable)expression));
        if (expression instanceof xowl.lang.actions.ArrayElement)
            return parent.toFunction(eval_ArrayElement(parent, (xowl.lang.actions.ArrayElement)expression));
        if (expression instanceof xowl.lang.interop.JavaInvokation)
            return parent.toFunction(eval_JavaInvokation(parent, (xowl.lang.interop.JavaInvokation)expression));
        if (expression instanceof xowl.lang.interop.ObjectField)
            return parent.toFunction(eval_ObjectField(parent, (xowl.lang.interop.ObjectField)expression));
        if (expression instanceof xowl.lang.interop.StaticField)
            return parent.toFunction(eval_StaticField(parent, (xowl.lang.interop.StaticField)expression));
        if (expression instanceof xowl.lang.owl2.IRI) return eval_Function(parent, (xowl.lang.owl2.IRI)expression);
        throw getUnknownExpression(expression);
    }
    protected abstract xowl.lang.runtime.Function eval_Function(Evaluator parent, xowl.lang.owl2.IRI expression) throws xowl.interpreter.XOWLException;
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="evalClosure">
    @Override public xowl.lang.runtime.Closure evalClosure(Evaluator parent, xowl.lang.actions.ExecutableExpression expression) throws xowl.interpreter.XOWLException {
        if (expression == null) return null;
        if (expression instanceof xowl.lang.actions.Invoke)
            return parent.toClosure(eval_Invoke(parent, (xowl.lang.actions.Invoke)expression));
        if (expression instanceof xowl.lang.actions.Execute)
            return parent.toClosure(eval_Execute(parent, (xowl.lang.actions.Execute)expression));
        if (expression instanceof xowl.lang.actions.ValueOf)
            return parent.toClosure(eval_ValueOf(parent, (xowl.lang.actions.ValueOf)expression));
        if (expression instanceof xowl.lang.actions.CodeVariable)
            return parent.toClosure(eval_CodeVariable(parent, (xowl.lang.actions.CodeVariable)expression));
        if (expression instanceof xowl.lang.actions.QueryVariable)
            return parent.toClosure(eval_QueryVariable(parent, (xowl.lang.actions.QueryVariable)expression));
        if (expression instanceof xowl.lang.actions.ArrayElement)
            return parent.toClosure(eval_ArrayElement(parent, (xowl.lang.actions.ArrayElement)expression));
        if (expression instanceof xowl.lang.interop.JavaInvokation)
            return parent.toClosure(eval_JavaInvokation(parent, (xowl.lang.interop.JavaInvokation)expression));
        if (expression instanceof xowl.lang.interop.ObjectField)
            return parent.toClosure(eval_ObjectField(parent, (xowl.lang.interop.ObjectField)expression));
        if (expression instanceof xowl.lang.interop.StaticField)
            return parent.toClosure(eval_StaticField(parent, (xowl.lang.interop.StaticField)expression));
        if (expression instanceof xowl.lang.actions.Lambda)
            return eval_Lambda(parent, (xowl.lang.actions.Lambda)expression);
        throw getUnknownExpression(expression);
    }
    protected xowl.lang.runtime.Closure eval_Lambda(Evaluator parent, xowl.lang.actions.Lambda expression) throws xowl.interpreter.XOWLException {
        // Static evaluation of lambda expressions into closures
        // this function is only used when loading a file, it creates a closure with an empty context
        xowl.lang.runtime.Closure closure = new xowl.lang.runtime.Closure();
        xowl.lang.runtime.LexicalContext context = new xowl.lang.runtime.LexicalContext();
        closure.setCloses(expression);
        closure.setContext(context);
        return closure;
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="evalArray">
    @Override public xowl.lang.runtime.Array evalArray(Evaluator parent, xowl.lang.actions.ArrayExpression expression) throws xowl.interpreter.XOWLException {
        if (expression == null) return null;
        if (expression instanceof xowl.lang.actions.Invoke)
            return parent.toArray(eval_Invoke(parent, (xowl.lang.actions.Invoke)expression));
        if (expression instanceof xowl.lang.actions.Execute)
            return parent.toArray(eval_Execute(parent, (xowl.lang.actions.Execute)expression));
        if (expression instanceof xowl.lang.actions.ValuesOf)
            return parent.toArray(eval_ValuesOf(parent, (xowl.lang.actions.ValuesOf)expression));
        if (expression instanceof xowl.lang.actions.CodeVariable)
            return parent.toArray(eval_CodeVariable(parent, (xowl.lang.actions.CodeVariable)expression));
        if (expression instanceof xowl.lang.actions.QueryVariable)
            return parent.toArray(eval_QueryVariable(parent, (xowl.lang.actions.QueryVariable)expression));
        if (expression instanceof xowl.lang.actions.ArrayElement)
            return parent.toArray(eval_ArrayElement(parent, (xowl.lang.actions.ArrayElement)expression));
        if (expression instanceof xowl.lang.interop.JavaInvokation)
            return parent.toArray(eval_JavaInvokation(parent, (xowl.lang.interop.JavaInvokation)expression));
        if (expression instanceof xowl.lang.interop.ObjectField)
            return parent.toArray(eval_ObjectField(parent, (xowl.lang.interop.ObjectField)expression));
        if (expression instanceof xowl.lang.interop.StaticField)
            return parent.toArray(eval_StaticField(parent, (xowl.lang.interop.StaticField)expression));
        if (expression instanceof xowl.lang.actions.Array)
            return eval_Array(parent, (xowl.lang.actions.Array)expression);
        if (expression instanceof xowl.lang.actions.Concat)
            return eval_Concat(parent, (xowl.lang.actions.Concat)expression);
        if (expression instanceof xowl.lang.actions.Slice)
            return eval_Slice(parent, (xowl.lang.actions.Slice)expression);
        throw getUnknownExpression(expression);
    }
    protected abstract xowl.lang.runtime.Array eval_Array(Evaluator parent, xowl.lang.actions.Array expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Array eval_Concat(Evaluator parent, xowl.lang.actions.Concat expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.Array eval_Slice(Evaluator parent, xowl.lang.actions.Slice expression) throws xowl.interpreter.XOWLException;
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="evalJavaObject">
    @Override public xowl.lang.runtime.JavaObject evalJavaObject(Evaluator parent, xowl.lang.interop.JavaObjectExpression expression) throws xowl.interpreter.XOWLException {
        if (expression == null) return null;
        if (expression instanceof xowl.lang.actions.Invoke)
            return parent.toJavaObject(eval_Invoke(parent, (xowl.lang.actions.Invoke)expression));
        if (expression instanceof xowl.lang.actions.Execute)
            return parent.toJavaObject(eval_Execute(parent, (xowl.lang.actions.Execute)expression));
        if (expression instanceof xowl.lang.actions.CodeVariable)
            return parent.toJavaObject(eval_CodeVariable(parent, (xowl.lang.actions.CodeVariable)expression));
        if (expression instanceof xowl.lang.interop.JavaInvokation)
            return eval_JavaInvokation(parent, (xowl.lang.interop.JavaInvokation)expression);
        if (expression instanceof xowl.lang.interop.NewObject)
            return eval_NewObject(parent, (xowl.lang.interop.NewObject)expression);
        if (expression instanceof xowl.lang.interop.ObjectField)
            return eval_ObjectField(parent, (xowl.lang.interop.ObjectField)expression);
        if (expression instanceof xowl.lang.interop.StaticField)
            return eval_StaticField(parent, (xowl.lang.interop.StaticField)expression);
        throw getUnknownExpression(expression);
    }
    protected abstract xowl.lang.runtime.JavaObject eval_JavaInvokation(Evaluator parent, xowl.lang.interop.JavaInvokation expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.JavaObject eval_NewObject(Evaluator parent, xowl.lang.interop.NewObject expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.JavaObject eval_ObjectField(Evaluator parent, xowl.lang.interop.ObjectField expression) throws xowl.interpreter.XOWLException;
    protected abstract xowl.lang.runtime.JavaObject eval_StaticField(Evaluator parent, xowl.lang.interop.StaticField expression) throws xowl.interpreter.XOWLException;
    // </editor-fold>

    @Override public xowl.lang.runtime.Value evaluate(Evaluator parent, xowl.lang.owl2.Expression expression) throws xowl.interpreter.XOWLException {
        if (expression == null) return null;
        if (expression instanceof xowl.lang.actions.Invoke) return eval_Invoke(parent, (xowl.lang.actions.Invoke)expression);
        if (expression instanceof xowl.lang.actions.Execute) return eval_Execute(parent, (xowl.lang.actions.Execute)expression);
        if (expression instanceof xowl.lang.actions.Contains) return eval_Contains(parent, (xowl.lang.actions.Contains)expression);
        if (expression instanceof xowl.lang.actions.ValueOf) return eval_ValueOf(parent, (xowl.lang.actions.ValueOf)expression);
        if (expression instanceof xowl.lang.actions.ValuesOf) return eval_ValuesOf(parent, (xowl.lang.actions.ValuesOf)expression);
        if (expression instanceof xowl.lang.actions.CodeVariable) return eval_CodeVariable(parent, (xowl.lang.actions.CodeVariable)expression);
        if (expression instanceof xowl.lang.actions.QueryVariable) return eval_QueryVariable(parent, (xowl.lang.actions.QueryVariable)expression);
        if (expression instanceof xowl.lang.actions.ArrayElement) return eval_ArrayElement(parent, (xowl.lang.actions.ArrayElement)expression);
        if (expression instanceof xowl.lang.interop.JavaInvokation) return eval_JavaInvokation(parent, (xowl.lang.interop.JavaInvokation)expression);
        if (expression instanceof xowl.lang.interop.ObjectField) return eval_ObjectField(parent, (xowl.lang.interop.ObjectField)expression);
        if (expression instanceof xowl.lang.interop.StaticField) return eval_StaticField(parent, (xowl.lang.interop.StaticField)expression);
        if (expression instanceof xowl.lang.owl2.EntityExpression)
            return evalEntity(parent, (xowl.lang.owl2.EntityExpression)expression);
        if (expression instanceof xowl.lang.owl2.ClassExpression)
            return evalClass(parent, (xowl.lang.owl2.ClassExpression)expression).getInterpretationOf();
        if (expression instanceof xowl.lang.owl2.ObjectPropertyExpression)
            return evalObjProp(parent, (xowl.lang.owl2.ObjectPropertyExpression)expression).getInterpretationOf();
        if (expression instanceof xowl.lang.owl2.DataPropertyExpression)
            return evalDataProp(parent, (xowl.lang.owl2.DataPropertyExpression)expression).getInterpretationOf();
        if (expression instanceof xowl.lang.owl2.Datarange)
            return evalDatatype(parent, (xowl.lang.owl2.Datarange)expression).getInterpretationOf();
        if (expression instanceof xowl.lang.owl2.IndividualExpression) {
            xowl.lang.runtime.Individual individual = evalIndividual(parent, (xowl.lang.owl2.IndividualExpression)expression);
            if (individual == null)
                return null;
            if (individual instanceof xowl.lang.runtime.NamedIndividual)
                return ((xowl.lang.runtime.NamedIndividual)individual).getInterpretationOf();
            else
                return ((xowl.lang.owl2.AnonymousIndividual)individual);
        }
        if (expression instanceof xowl.lang.owl2.LiteralExpression)
            return evalLiteral(parent, (xowl.lang.owl2.LiteralExpression)expression);
        if (expression instanceof xowl.lang.actions.FunctionExpression)
            return evalFunction(parent, (xowl.lang.actions.FunctionExpression)expression).getInterpretationOf();
        if (expression instanceof xowl.lang.actions.ExecutableExpression)
            return evalClosure(parent, (xowl.lang.actions.ExecutableExpression)expression);
        if (expression instanceof xowl.lang.actions.ArrayExpression)
            return evalArray(parent, (xowl.lang.actions.ArrayExpression)expression);
        if (expression instanceof xowl.lang.interop.JavaObjectExpression)
            return evalJavaObject(parent, (xowl.lang.interop.JavaObjectExpression)expression);
        throw getUnknownExpression(expression);
    }

    @Override public xowl.lang.runtime.Entity toEntity(xowl.lang.runtime.Value value) throws xowl.interpreter.XOWLException { throw getNotImplemented(); }
    @Override public xowl.lang.runtime.Class toClass(xowl.lang.runtime.Value value) throws xowl.interpreter.XOWLException { throw getNotImplemented(); }
    @Override public xowl.lang.runtime.ObjectProperty toObjProp(xowl.lang.runtime.Value value) throws xowl.interpreter.XOWLException { throw getNotImplemented(); }
    @Override public xowl.lang.runtime.DataProperty toDataProp(xowl.lang.runtime.Value value) throws xowl.interpreter.XOWLException { throw getNotImplemented(); }
    @Override public xowl.lang.runtime.Datatype toDatatype(xowl.lang.runtime.Value value) throws xowl.interpreter.XOWLException { throw getNotImplemented(); }
    @Override public xowl.lang.runtime.Individual toIndividual(xowl.lang.runtime.Value value) throws xowl.interpreter.XOWLException { throw getNotImplemented(); }
    @Override public xowl.lang.runtime.Literal toLiteral(xowl.lang.runtime.Value value) throws xowl.interpreter.XOWLException { throw getNotImplemented(); }
    @Override public xowl.lang.runtime.Function toFunction(xowl.lang.runtime.Value value) throws xowl.interpreter.XOWLException { throw getNotImplemented(); }
    @Override public xowl.lang.runtime.Closure toClosure(xowl.lang.runtime.Value value) throws xowl.interpreter.XOWLException { throw getNotImplemented(); }
    @Override public xowl.lang.runtime.Array toArray(xowl.lang.runtime.Value value) throws xowl.interpreter.XOWLException { throw getNotImplemented(); }
    @Override public xowl.lang.runtime.JavaObject toJavaObject(xowl.lang.runtime.Value value) throws xowl.interpreter.XOWLException { throw getNotImplemented(); }


    
    protected xowl.interpreter.XOWLException getUnknownExpression(xowl.lang.owl2.Expression expression) {
        return new xowl.interpreter.XOWLException("Unknwown expression type: " + expression.getClass().getName());
    }
    protected xowl.interpreter.XOWLException getNotImplemented() {
        return new xowl.interpreter.XOWLException("Not implemented");
    }
}
